package cate.game.pvp.jungle;

import cate.game.framework.ModuleMan;
import cate.game.framework.ThreadShare;
import cate.game.pvp.jungle.core.JungleBuffVO;
import cate.game.pvp.jungle.core.JungleTaskData;
import cate.game.pvp.jungle.core.JungleTaskDetailVO;
import cate.game.pvp.jungle.msg.*;
import cate.game.role.Role;
import cate.game.role.RoleSnapshot;
import cp.solution.rpc.RpcMsgHead;
import easy.java.dev.note.NoteClass;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@NoteClass("丛林冒险-游戏服管理")
public class JungleManager extends ModuleMan {
    @Override
    public void initDependent() throws Exception {
        // 加载常量
        JungleConstants.loadFromTable(game.table.common);
        // RPC监听
        game.rpcRecv().onFireAndForgetTemplate(JungleInnerMsg.TASK_FINISH_EVENT, JungleFinishEvent.class, this::handleFinishEvent);
        game.rpcRecv().onFireAndForgetTemplate(JungleInnerMsg.BROADCAST_OVERALL, JungleOverallVO.class, this::handleBroadcastOverall);
        game.rpcRecv().onFireAndForgetTemplate(JungleInnerMsg.BROADCAST_BUFF, JungleBuffVO.class, this::handleBroadcastBuff);
        game.rpcRecv().onFireAndForgetTemplate(JungleInnerMsg.ADD_ROB_REPORT, JungleAddRobReport.class, this::handleAddRobReport);
        game.rpcRecv().onFireAndForgetTemplate(JungleInnerMsg.TASK_CHANGE, JungleTaskData.class, this::handleTaskChange);
    }

    /**
     * 收到广播概览变更
     *
     * @param head 消息头
     * @param vo   概览信息
     */
    private void handleBroadcastOverall(RpcMsgHead head, JungleOverallVO vo) {
        game.role.activeForOnline(role -> {
            if (role.getPvp().jungle.viewing) {
                role.getPvp().jungle.sendOverall(vo);
            }
        });
    }

    /**
     * 收到广播BUFF变更
     *
     * @param head 消息头
     * @param vo   BUFF信息
     */
    private void handleBroadcastBuff(RpcMsgHead head, JungleBuffVO vo) {
        game.role.activeForOnline(role -> {
            if (role.getPvp().jungle.viewing) {
                role.getPvp().jungle.sendBuffInfo(vo);
            }
        });
    }

    /**
     * 通知跨服触发BUFF
     */
    public void sendTriggerBuff(Role role) {
        game.rpcSend().fireAndForgetCross(JungleInnerMsg.TRIGGER_BUFF, new RoleSnapshot(role));
    }

    /**
     * 获取我当前的任务
     *
     * @param role 玩家
     * @return 任务
     */
    public JungleTaskData getMyCurrentTask(Role role) {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.MY_CURRENT_TASK, role.getUid(), JungleTaskData.class);
    }

    /**
     * 查看概览信息
     *
     * @return 概览信息
     */
    public JungleOverallVO viewOverall() {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.VIEW_OVERALL, null, JungleOverallVO.class);
    }

    /**
     * 查看BUFF信息
     *
     * @return BUFF信息
     */
    public JungleBuffVO viewBuffs() {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.VIEW_BUFF, null, JungleBuffVO.class);
    }

    /**
     * 查看任务详情
     *
     * @param targetUid 目标UID
     * @return 任务详情
     */
    public JungleTaskDetailVO viewDetail(String targetUid) {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.VIEW_DETAIL, targetUid, JungleTaskDetailVO.class);
    }

    /**
     * 发起派遣任务
     *
     * @param req 请求数据
     * @return 返回数据
     */
    public JungleStartTaskRet startTask(JungleStartTaskReq req) {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.START_TASK, req, JungleStartTaskRet.class);
    }

    /**
     * 获取忙碌的UID列表
     *
     * @param uidList 原始列表
     */
    public List<String> supportBusy(List<String> uidList) {
        if (uidList.isEmpty()) {
            return new ArrayList<>();
        }
        return Optional.ofNullable(game.rpcSend().requestResponseCross(JungleInnerMsg.SUPPORT_BUSY, new JungleSupportUidList(uidList), JungleSupportUidList.class))
                .map(ret -> ret.uidList).orElse(new ArrayList<>());
    }

    /**
     * 处理任务结算
     *
     * @param head  消息头
     * @param event 结算事件信息
     */
    private void handleFinishEvent(RpcMsgHead head, JungleFinishEvent event) {
        Role role = game.role.getRole(event.roleUid);
        if (role == null) {
            log.error("接受任务完结事件失败!找不到这个人 事件:[{}]", event);
            return;
        }
        if (role.getStatus().isOnline()) {
            ThreadShare.instance().exe(role, () -> role.getPvp().jungle.handleTaskFinish(event.fin));
        } else {
            role.getPvp().jungle.handleTaskFinish(event.fin);
        }
    }

    /**
     * 加速任务
     *
     * @param role 玩家
     * @return 是否加速成功
     */
    public boolean speedUp(Role role) {
        return Optional.ofNullable(game.rpcSend().requestResponseCross(JungleInnerMsg.COST_SPEED_UP, role.getUid(), Boolean.class))
                .orElse(false);
    }

    /**
     * 发起掠夺
     *
     * @param req 请求
     * @return 返回
     */
    public JungleRobRet robTask(JungleRobReq req) {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.ROB_TASK, req, JungleRobRet.class);
    }

    /**
     * 上报掠夺结果
     *
     * @param req 请求
     * @return 返回
     */
    public JungleRobReportRet robReport(JungleRobReportReq req) {
        return game.rpcSend().requestResponseCross(JungleInnerMsg.ROB_RESULT_REPORT, req, JungleRobReportRet.class);
    }

    /**
     * 收到跨服通知添加战报
     *
     * @param head 消息头
     * @param msg  战报消息
     */
    private void handleAddRobReport(RpcMsgHead head, JungleAddRobReport msg) {
        if (msg == null || msg.report == null) {
            return;
        }
        Role role = game.role.getRole(msg.roleUid);
        if (role.getStatus().isOnline()) {
            ThreadShare.instance().exe(role, () -> {
                role.getPvp().jungle.addReport(msg.report);
                role.getPvp().jungle.noticeUpdate();
            });
        } else {
            role.getPvp().jungle.addReport(msg.report);
        }
    }

    /**
     * 任务数据变更
     *
     * @param head
     * @param taskData
     */
    private void handleTaskChange(RpcMsgHead head, JungleTaskData taskData) {
        Role role = game.role.getRoleFromActive(taskData.owner.uid);
        if (role == null || !role.getStatus().isOnline()) {
            return;
        }
        ThreadShare.instance().exe(role, () -> {
            role.getPvp().jungle.current = taskData;
            role.getPvp().jungle.noticeUpdate();
        });
    }
}
